/**
 * Copyright (c) 2008, George Taylor
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted 
 * provided that the following conditions are met:
 * 
 *   * Redistributions of source code must retain the above copyright notice, this list of 
 *     conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright notice, this list of 
 *     conditions and the following disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *   * Neither the name of the copyright holder's organization nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software without specific 
 *     prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package uk.co.taylorconsulting.annoweb.web.builder;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;

import org.apache.log4j.Logger;

import uk.co.taylorconsulting.annoweb.web.builder.data.Site;

public class ControllerBuilder {
	private static final Logger            LOG      = Logger.getLogger(ControllerBuilder.class);
	private static final ControllerBuilder instance = new ControllerBuilder();
	
	public static void buildSite(HashMap<String, Site> sites, File tmpLocation) {
		instance.buildSite(sites, tmpLocation, true);
	}
	
	public void buildSite(HashMap<String, Site> sites, File tmpLocation, boolean ok) {
		File siteFile = new File(tmpLocation, "TCSiteController.java");
		StringBuffer str = addClassStart(sites);
		str.append("}\n");
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(siteFile);
			fos.write(str.toString().getBytes());
			fos.close();
		} catch (Exception e) {
			LOG.warn("Error writing class to " + siteFile.getAbsolutePath() + "(" + e.getMessage() + ")");
		}
	}
	
	private StringBuffer addClassStart(HashMap<String, Site> sites) {
		Site defaultSite = sites.get("xxDefaultxx");
		StringBuffer str = new StringBuffer("import javax.servlet.http.*;\n");
		str.append("import javax.servlet.*;\n");
		str.append("import java.util.*;\n");
		str.append("import org.apache.log4j.Logger;\n");
		str.append("public class TCSiteController extends uk.co.taylorconsulting.web.controller.WebHelper implements uk.co.taylorconsulting.web.controller.WebFramework {\n");
		str.append("\tprivate static final Logger LOG = Logger.getLogger(TCSiteController.class);\n");
		str.append("\tprivate static final ").append("TCSiteController instance = new ").append("TCSiteController").append("();\n");
		str.append("\tpublic ").append("TCSiteController(){}\n");
		str.append("\tpublic static TCSiteController getInstance() {\n");
		str.append("\t\treturn instance;\n");
		str.append("\t}\n");
		str.append("\tprivate enum Actions {system_quicklink");
		for (Site s : sites.values()) {
			str.append(",");
			str.append(s.getName().toLowerCase());
		}
		str.append(";\n");
		str.append("\t}\n");
		str.append("\tpublic void process(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {\n");
		str.append("\t\ttry {\n");
		str.append("\t\t\tString req = request.getServletPath().toLowerCase();\n");
		str.append("\t\t\treq = req.substring(1);\n");
		str.append("\t\t\treq = req.substring(0,req.indexOf(\"").append(defaultSite.getExt().toLowerCase()).append("\")-1);\n");
		str.append("\t\t\tLOG.debug(\"action=\"+req);\n");
		str.append("\t\t\tActions dispatcher = Actions.valueOf(req);\n");
		str.append("\t\t\tswitch (dispatcher) {\n");
		Site defSite = null;
		for (Site s : sites.values()) {
			if (s.getName().equals("xxDefaultxx")) {
				defSite = s;
			}
			str.append("\t\t\t\tcase ").append(s.getName().toLowerCase()).append(": {\n");
			str.append("\t\t\t\t\t((Site").append(s.getName()).append(")getCache(\"Site").append(s.getName()).append("\")).process(request, response, servletContext);\n");
			str.append("\t\t\t\t\treturn;\n");
			str.append("\t\t\t\t}\n");
		}
		str.append("\t\t\t\tcase system_quicklink: {\n");
		str.append("\t\t\t\t\t((SystemQuickLink)getCache(\"SystemQuickLink\")).process(request, response, servletContext);\n");
		str.append("\t\t\t\t\treturn;\n");
		str.append("\t\t\t\t}\n");
		str.append("\t\t\t}\n");
		str.append("\t\t} catch (Throwable t) {}\n");
		if (defSite != null) {
			str.append("\t\t((Site").append(defSite.getName()).append(")getCache(\"Site").append(defSite.getName()).append("\")).process(request, response, servletContext);\n");
		} else {
			str.append("\t\tLOG.warn(\"Cannot process request. Action not defined for path: \"+request.getServletPath());\n");
		}
		str.append("\t}\n");
		return str;
	}
}
